﻿/*
 * serialport.cpp
 *
 *  Created on: 2016年12月18日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_OS_COM DM_API_EXPORT

#include <dm/os/com/serialdevice.hpp>
#include <dm/os/log/logger.hpp>

using namespace boost::asio;

namespace dm{
namespace os{
namespace com{

static const char* logModule = "CSerialDevice.com.os.dm";

CSerialDevice::CSerialDevice( ios_t& ios,size_t rxBuffSize ):CDevice(rxBuffSize),
		m_dev(ios){
	log().debug( THISMODULE "创建对象");
}

CSerialDevice::~CSerialDevice(){
	log().debug( THISMODULE "销毁对象");
	m_dev.close();
}

bool CSerialDevice::checkAndSetAddress( const CSerialAddr& addr ){
	m_addr = addr;
	return true;
}

bool CSerialDevice::startConnect(){
	log().debug( THISMODULE "打开设备%s",m_addr.toString().c_str());
	try{
		const CSerialAddr* addr = m_addr.asSerialPort();
		if( !addr )
			return false;

		m_dev.open(addr->getDevice());

		m_dev.set_option( serial_port::baud_rate(addr->getBps()));
		m_dev.set_option( serial_port::character_size(addr->getCharBits()));

		switch( addr->getStop() ){
		case CSerialAddr::Two:
			m_dev.set_option( serial_port::stop_bits(serial_port::stop_bits::two));
			break;
		case CSerialAddr::OneAndHalf:
			m_dev.set_option( serial_port::stop_bits(serial_port::stop_bits::onepointfive));
			break;
		default:
			m_dev.set_option( serial_port::stop_bits(serial_port::stop_bits::one));
		}

		switch( addr->getParity() ){
		case CSerialAddr::Even:
			m_dev.set_option( serial_port::parity(serial_port::parity::even));
			break;
		case CSerialAddr::Odd:
			m_dev.set_option( serial_port::parity(serial_port::parity::odd));
			break;
		default:
			m_dev.set_option( serial_port::parity(serial_port::parity::none));
		}

		switch( addr->getFlowCtl() ){
		case CSerialAddr::Soft:
			m_dev.set_option( serial_port::flow_control(serial_port::flow_control::software));
			break;
		case CSerialAddr::Hardware:
			m_dev.set_option( serial_port::flow_control(serial_port::flow_control::hardware));
			break;
		default:
			m_dev.set_option( serial_port::flow_control(serial_port::flow_control::none));
		}

		handler_connect();
	}catch( std::exception& ec ){
		log().warnning( THISMODULE "open %s fail(%s)",m_addr.toString().c_str(),ec.what());
		handler_connect(boost::system::errc::make_error_code(boost::system::errc::bad_address));
		return false;
	}

	return true;
}

bool CSerialDevice::stopConnect(){
	m_dev.close();
	return true;
}

bool CSerialDevice::startSend( const dm::uint8* buf,const size_t& len ){
	log().debug(THISMODULE "tx %d bytes",len);
	try{
		boost::asio::async_write(m_dev,boost::asio::buffer(buf,len),boost::bind(&CSerialDevice::handler_tx,this,boost::asio::placeholders::error));
	}catch( std::exception& ec ){
		log().warnning(THISMODULE "send %d bytes fail(%s)",len,ec.what());
		return false;
	}
	return true;
}

void CSerialDevice::start_rx(){
	try{
		m_dev.async_read_some(buffer(m_rxBuf.get(),m_rxBufSize),boost::bind(&CSerialDevice::handler_rx,this,placeholders::error,placeholders::bytes_transferred));
	}catch( std::exception& ec ){
		log().error(THISMODULE "开启监听失败%s",ec.what());
	}
}

void CSerialDevice::cancelDev(){
	try{
		m_dev.cancel();
	}catch( std::exception& ec ){
		log().error(THISMODULE "取消设备失败%s",ec.what());
	}

}

}
}
}


